/************************************************************************
 * @file PluginDescription.cpp
 * @author Ian Chen
 * @version 1.0
 *
 * @section LICENSE
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details at
 * http://www.gnu.org/licenses/lgpl.html
 *
 ************************************************************************/
#include <plugin/plugin/PluginDescription.h>

#include <QCoreApplication>
#include <QDir>

namespace antu
{
namespace plugin
{

PluginDescription::PluginDescription(const QString &name, const PluginVersion &version, const PluginVersion &minimumCompatibleVersion)
    : m_sName(name),
      m_iStartLevel(100)
{
    this->m_oVersion = version;
    this->m_oMinimumCompatibleVersion = minimumCompatibleVersion;
}

PluginDescription::PluginDescription(const QString &name, const QString &versionString, const QString &minimumCompatibleVersion)
    : m_sName(name),
      m_oVersion(versionString),
      m_oMinimumCompatibleVersion(minimumCompatibleVersion),
      m_iStartLevel(100)
{
}

PluginDescription::~PluginDescription()
{
}

QString PluginDescription::name() const
{
    return this->m_sName;
}

PluginVersion PluginDescription::version() const
{
    return this->m_oVersion;
}

PluginVersion PluginDescription::minimumCompatibleVersion() const
{
    return this->m_oMinimumCompatibleVersion;
}

QString PluginDescription::path() const
{
    return this->m_sPath;
}

void PluginDescription::setPath(const QString &path)
{
    QString p = qApp->applicationDirPath();

#ifdef Q_OS_UNIX
    path = QObject::tr("lib") + path;
#endif
    QDir dir(p);
    this->m_sPath = dir.absoluteFilePath(path);
}

int PluginDescription::startLevel() const
{
    return this->m_iStartLevel;
}

void PluginDescription::setStartLevel(int startLevel)
{
    this->m_iStartLevel = startLevel;
}

bool PluginDescription::isSupportedApplicationGroup(const QString &groupName) const
{
    if (this->m_oApplicationGroups.contains(PluginDescription::UNIVERSAL_APP_GROUP))
        return true;

    if (this->m_oApplicationGroups.contains(groupName, Qt::CaseInsensitive))
        return true;
    return false;
}

bool PluginDescription::isSupportedApplicationGroup(const QStringList &groups) const
{
    if (groups.contains(PluginDescription::UNIVERSAL_APP_GROUP))
        return true;

    for (int i = 0; i < this->m_oApplicationGroups.size(); i++)
    {
        if (groups.contains(this->m_oApplicationGroups[i], Qt::CaseInsensitive))
            return true;
    }
    return false;
}

void PluginDescription::addApplicationGroup(const QString &groupName)
{
    if (!this->m_oApplicationGroups.contains(groupName, Qt::CaseInsensitive))
        this->m_oApplicationGroups.append(groupName);
}

void PluginDescription::addDependency(const PluginRequirement &requirement)
{
    this->m_vRequiredPlugins.push_back(requirement);
}

PluginRequirement PluginDescription::requirementAt(size_t pos) const
{
    if (pos < 0 || pos >= this->m_vRequiredPlugins.size())
    {
        throw "position out of range";
    }
    return this->m_vRequiredPlugins.at(pos);
}

size_t PluginDescription::requirementCount() const
{
    return this->m_vRequiredPlugins.size();
}

bool PluginDescription::operator ==(const PluginDescription &description) const
{
    if (this->code() == description.code() &&
            this->name() == description.name())
    {
        return true;
    }
    return false;
}

bool PluginDescription::isRequiredPlugin(const QString &code) const
{
    vector<PluginRequirement>::const_iterator beginIter = this->m_vRequiredPlugins.begin();
    vector<PluginRequirement>::const_iterator endIter = this->m_vRequiredPlugins.end();

    for (; beginIter != endIter; beginIter++)
    {
        if (beginIter->code() == code)
            return true;
    }
    return false;
}

const QString PluginDescription::UNIVERSAL_APP_GROUP = "ATTGNRC";

}
}
